package com.cooldatasoft.taskManager.user.gui;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;

import com.cooldatasoft.domain.model.Project;
import com.cooldatasoft.domain.model.Task;
import com.cooldatasoft.domain.model.UserProjectRoles;
import com.cooldatasoft.domain.service.RolesService;
import com.cooldatasoft.domain.service.TaskService;
import com.cooldatasoft.domain.service.UserProjectRolesService;
import com.cooldatasoft.security.TaskManagerSecurityManager;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Item;
import com.vaadin.data.util.BeanItem;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.data.validator.StringLengthValidator;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.DefaultFieldFactory;
import com.vaadin.ui.Field;
import com.vaadin.ui.Form;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.NativeButton;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;

@Configurable(preConstruction=true)
public class AddTaskView extends CustomComponent {

	@AutoGenerated
	private VerticalLayout mainLayout;
	@AutoGenerated
	private HorizontalLayout buttonsLayout;
	@AutoGenerated
	private NativeButton resetBtn;
	@AutoGenerated
	private NativeButton submitBtn;
	@AutoGenerated
	private VerticalLayout taskFormLayout;

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

	@Autowired
	private UserProjectRolesService userProjectRolesService;
	@Autowired
	private RolesService roleService;
	@Autowired
	private TaskManagerSecurityManager securityManager;
	@Autowired
	private TaskService taskService;

	private static final long serialVersionUID = 1L;
	private Form form;
	private Task task;
	private BeanItem<Task> taskItem;
	private ComboBox comb;

	public AddTaskView() {
		buildMainLayout();
		setCompositionRoot(mainLayout);
		customizeTaskForm();
		customizeButtons();
	}

	private void customizeButtons() {
		submitBtn.addListener(new Button.ClickListener() {
			
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				form.commit();;
				task.setTaskStatus("to do");
				
				taskService.insertTask(task);				
				
				getWindow().getParent().showNotification("New task succesfully created");		
				(getWindow().getParent()).removeWindow(getWindow());
			}
		});
		
		resetBtn.addListener(new Button.ClickListener() {
			
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				form.discard();				
			}
		});
		
	}

	private void customizeTaskForm() {
		task = new Task();
		taskItem = new BeanItem<Task>(task);
		form = new FormWithComplexLayout(taskItem);
		
		form.setCaption("Fill task data");
		form.setWriteThrough(false);
		form.setInvalidCommitted(false);

		taskFormLayout.addComponent(form);		
	}

	public class FormWithComplexLayout extends Form {

		private static final long serialVersionUID = 1L;
		private GridLayout ourLayout;

		public FormWithComplexLayout(BeanItem<Task> taskItem) {

			ourLayout = new GridLayout(2, 4);
			ourLayout.setMargin(true, false, false, true);
			ourLayout.setSpacing(true);
			setLayout(ourLayout);

			setWriteThrough(false); 
			setInvalidCommitted(false); 

			setFormFieldFactory(new ProjectFieldFactory());
			setItemDataSource(taskItem); 

			setVisibleItemProperties(Arrays.asList(new String[] { "taskName", "taskDescription", "taskType", "taskStatus", "project" }));
		}

		@Override
		protected void attachField(Object propertyId, Field field) {
			if (propertyId.equals("taskName")) {
				ourLayout.addComponent(field, 0, 0);
			} else if (propertyId.equals("taskType")) {
				ourLayout.addComponent(field, 1, 0);
			} else if (propertyId.equals("taskDescription")) {
				ourLayout.addComponent(field, 0, 1, 1, 1);
			} else if (propertyId.equals("taskStatus")) {
				ourLayout.addComponent(field, 0, 2);
			} else if (propertyId.equals("project")) {
				ourLayout.addComponent(field, 1, 2);
			} 
	}
	
	private class ProjectFieldFactory extends DefaultFieldFactory {

		private static final long serialVersionUID = 1L;
		private static final String COMMON_FIELD_WIDTH = "150px";
		private static final String DOUBLE_FIELD_WIDTH = "320px";	
		
		ComboBox projects = new ComboBox();
		
		@SuppressWarnings("deprecation")
		public ProjectFieldFactory() {
			List<UserProjectRoles> userProjectRoles = new ArrayList<UserProjectRoles>();
			List<Project> userProjects = new ArrayList<Project>();
			
			userProjectRoles = userProjectRolesService.getUserProjectRolesByIdUser(securityManager.getCurrentUser());
			if(userProjectRoles != null){
				for(UserProjectRoles p : userProjectRoles) {
					userProjects.add(p.getIdProject());
				}
			}
			
			if(userProjects.size() > 0){
				BeanItemContainer<Project> container = new BeanItemContainer<Project>(userProjects);
				projects.setContainerDataSource(container);
			}
			projects.setItemCaptionPropertyId("name");
			projects.setNullSelectionAllowed(false);
			projects.setCaption("Assign project");
		}

		@Override
		public Field createField(Item item, Object propertyId, Component uiContext) {
			Field f;	
			
			String[] taskTypes = {"Feature", "Issue", "Enhancement"};

			if ("taskDescription".equals(propertyId)) {
				f = createTextAreaField(propertyId);
			} else if ("project".equals(propertyId)) {
				return projects;
			} else if ("taskType".equals(propertyId)) {
				f = createComboBoxField(propertyId);
			} else {
				f = super.createField(item, propertyId, uiContext);
			}            

			if ("taskName".equals(propertyId)) {
				TextField tf = (TextField) f;
				tf.setNullRepresentation("");
				tf.setRequired(true);
				tf.setImmediate(true);
				tf.setRequiredError("Please enter a task name");
				tf.setWidth(COMMON_FIELD_WIDTH);
				tf.addValidator(new StringLengthValidator("Name must be 3-25 characters", 3, 50, false));
			} else if ("taskType".equals(propertyId)) {
				comb = (ComboBox) f;
				comb.setRequired(true);
				comb.setImmediate(true);
				comb.setRequiredError("Please select a task type");
				comb.setWidth(COMMON_FIELD_WIDTH);
				comb.setCaption("Task Type");
				comb.setNullSelectionAllowed(false);
				for(String type : taskTypes) {
					comb.addItem(type);
				}
			} else if ("taskDescription".equals(propertyId)) {
				TextArea ta = (TextArea) f;
				ta.setNullRepresentation("");
				ta.setCaption("Description");
				ta.setImmediate(true);
				ta.setRequired(true);
				ta.setRequiredError("Please enter project description");
				ta.setWidth(DOUBLE_FIELD_WIDTH);
			} else if("taskStatus".equals(propertyId)) {
				TextField tf = (TextField) f;
				tf.setInputPrompt("TO DO");
				tf.setEnabled(false);
				tf.setImmediate(true);
				tf.setWidth(COMMON_FIELD_WIDTH);
				tf.setNullRepresentation("");
			} 
			return f;
		}

		private TextArea createTextAreaField(Object propertyId) {
			TextArea ta = new TextArea();
			return ta;
		}
		
		private ComboBox createComboBoxField(Object propertyId) {
			ComboBox cb = new ComboBox();
			return cb;
		}
	}
}

	@AutoGenerated
	private VerticalLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new VerticalLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("100%");
		mainLayout.setHeight("100%");
		mainLayout.setMargin(false);
		
		// top-level component properties
		setWidth("100.0%");
		setHeight("100.0%");
		
		// taskFormLayout
		taskFormLayout = new VerticalLayout();
		taskFormLayout.setImmediate(false);
		taskFormLayout.setWidth("100.0%");
		taskFormLayout.setHeight("100.0%");
		taskFormLayout.setMargin(true);
		taskFormLayout.setSpacing(true);
		mainLayout.addComponent(taskFormLayout);
		mainLayout.setExpandRatio(taskFormLayout, 1.0f);
		
		// buttonsLayout
		buttonsLayout = buildButtonsLayout();
		mainLayout.addComponent(buttonsLayout);
		mainLayout.setComponentAlignment(buttonsLayout, new Alignment(9));
		
		return mainLayout;
	}

	@AutoGenerated
	private HorizontalLayout buildButtonsLayout() {
		// common part: create layout
		buttonsLayout = new HorizontalLayout();
		buttonsLayout.setImmediate(false);
		buttonsLayout.setWidth("-1px");
		buttonsLayout.setHeight("-1px");
		buttonsLayout.setMargin(true);
		buttonsLayout.setSpacing(true);
		
		// submitBtn
		submitBtn = new NativeButton();
		submitBtn.setCaption("Submit");
		submitBtn.setImmediate(true);
		submitBtn.setWidth("-1px");
		submitBtn.setHeight("-1px");
		submitBtn.setStyleName("defaultBtn");
		buttonsLayout.addComponent(submitBtn);
		
		// resetBtn
		resetBtn = new NativeButton();
		resetBtn.setCaption("Reset");
		resetBtn.setImmediate(true);
		resetBtn.setWidth("-1px");
		resetBtn.setHeight("-1px");
		resetBtn.setStyleName("defaultBtn");
		buttonsLayout.addComponent(resetBtn);
		
		return buttonsLayout;
	}

}
